Introducing X-Force Malware Threat Research public Github repository

an African-American man reading code on a large, digital wall display with his hands on his hips
Aaron Gdanski

Security Consultant, X-Force

IBM X-Force constantly analyzes different types of malware in order to provide insights to our stakeholders and conduct analysis of malicious campaigns. Throughout this process, X-Force often creates new tools to assist with the analysis of different file types and even specific malware families. X-Force also makes modifications to existing open-source projects that may enhance the ability of analysts to conduct analysis on various samples. In order to contribute to the community at large and showcase some of X-Force’s malware threat research, we are introducing our new GitHub page, located here. This GitHub page will contain all projects the X-Force Malware Threat Research team contributes to or creates for public use. Alongside the creation of this public GitHub, we are also open-sourcing a few of X-Force Malware Threat Research’s projects. These projects include:

  • Dragodis: A fork of a publicly available project located here. Dragodis is a framework that allows the creation of universal disassembler scripts. Our version adds support for IDA 8.5/9.x. Additionally, we added changes to account for samples with large auto-analysis times. We also opened pull requests to incorporate these changes into the main repository.
  • NSIS Reversing Suite (NRS): A fork of a publicly available project located here. NRS is a library written in Python that can be used to analyze NSIS installer executables. Our version adds support for additional executables, such as NSIS 2.x UTF-16LE format. We also added a disassembler, which allows for disassembling the NSIS code within NSIS installer files, as well as dumping the entire embedded install script.
  • GuloaderDumper: A tool to dump the payload from Guloader samples. Guloader is a popular commodity loader commonly seen associated with various infostealers such as VIPKeylogger.
  • DotNetUtils: A library written in Cython that can be used to parse, emulate and patch .NET executables.

Dragodis

Most malware is analyzed through the use of disassemblers. A disassembler is a program designed to parse and output the assembly instructions for an executable file. An essential component of the normal malware analysis workflow is disassembler scripting. Disassembler scripts can be used to automate various tasks that may be conducted over the course of analysis. For example, one may use disassembler scripting to parse out the configuration of various malware samples. 

The code snippet above is used to extract a configuration C2 address from a Golang application. Dragodis is used to communicate with the IDA disassembler in order to extract the proper C2 address.

Analysts may decide to use a different disassembler based on what suits their needs. Dragodis provides a common API to create disassembler scripts for various disassemblers. Created by the Department of Defense Cyber Crime Center (DC3), Dragodis currently supports two disassemblers: GHIDRA, a popular open-source tool created by the NSA, and IDA, a commercial product from Hex-Rays widely used in industry. X-Force has been contributing to Dragodis through the public repository. Our contributions include support for IDA 8.5/9.x as well as various important bugfixes related to certain scenarios that may come up during the course of analysis. This includes changes to prevent files with a long IDA load time from causing a Dragodis timeout error, as well as bugfixes relating to ARM shift registers.

In addition to contributing through the main public repository for Dragodis, X-Force Malware Threat Research maintains its own fork of Dragodis, which contains all of the latest changes we have made, located here.

NSIS Reversing Suite

Throughout the course of our research, we commonly come across different malicious loaders that make use of NSIS (Nullsoft Scriptable Installer System) installer executables. NSIS executables can be used by legitimate programs in order to install a program onto a computer. Executables created by NSIS will usually center around a single install script, which instructs the installer to take certain actions on the system. Sometimes these programs contain scripts that have additional IOCs and information required in order to further analyze the later stages of the malicious executable. Certain versions of 7-ZIP have the capability to extract NSIS scripts from their executables; however, it does not appear to be maintained and is also disabled in newer versions of 7-ZIP. In order to account for this gap in our parsing capabilities, we found NSIS Reversing Suite (NRS). NRS is a Python library created by isra17, which originally contained capabilities to parse basic information from an NSIS file, including embedded strings, blocks and sections.

NSIS version: 3.?
Unicode (UTF-16LE): True

FirstHeader @ 0x17800
        Flags:         0x00000000 (  )
        Siginfo:       0xdeadbeef
        Magics:        : “NullsoftInst”
        Header Size:   0x000cf856
        Inflated Size: 0x000026c4

Inflated header
        Flags:         0x00000080 ( CH_FLAGS_NO_ROOT_DIR )
Blocks[8]:
        Block[0] - Pages:
                File Offset:   0x0001792c
                Offset:        0x0000012c
                Num:           0x00000004
        Block[1] - Sections:
                File Offset:   0x00017a2c
                Offset:        0x0000022c
                Num:           0x00000001
        Block[2] - Entries:
                File Offset:   0x00018244
                Offset:        0x00000a44
                Num:           0x00000058
        Block[3] - Strings:
                File Offset:   0x00018be4
                Offset:        0x000013e4
                Num:           0x00000000
        Block[4] - Langtables:
                File Offset:   0x00019dd2
                Offset:        0x000025d2
                Num:           0x00000001
        Block[5] - CtlColors:
                File Offset:   0x00019ec4
                Offset:        0x000026c4
                Num:           0x00000000
        Block[6] - BgFont:
                File Offset:   0x00017800
                Offset:        0x00000000
                Num:           0x00000000
        Block[7] - Data:
                File Offset:   0x00017800
                Offset:        0x00000000
                Num:           0x00000000
        install_reg_rootkey: 0x00000000
        install_reg_key_ptr: 0x0000005b
        install_reg_value_ptr: 0x00000073
        bg_color1:     0x-0000001
        bg_color2:     0x-0000001
        bg_textcolor:  0x-0000001
        lb_bg:         0x00000000
        lb_fg:         0x0000ff00
        langtable_size: 0x000000f2
        license_bg:    0x-000000f
        code_onInit:   0x-0000001
        code_onInstSucess: 0x-0000001
        code_onInstFailed: 0x-0000001
        code_onUserAbort: 0x-0000001
        code_onGUIInit: 0x-0000001
        code_onGUIEnd: 0x-0000001
        code_onMouseOverSection: 0x-0000001
        code_onVerifyInstDir: 0x-0000001
        code_onSelChange: 0x-0000001
        code_onRebootFailed: 0x-0000001
        install_types:
                install_types[32]: 0x-0000026
        install_directory_ptr: %APPDATA%\kulegravedes\jay @ 0x00000047
        install_directory_auto_append: jay @ 0x00000057
        str_uninstchild:  @ 0x-0000001
        str_uninstcmd:  @ 0x-0000001
        str_wininit:   %WINDIR%\wininit.ini @ 0x000008e8
        blocks[NB_DATA].offset: 0x000180dc

Strings
        <All of the strings inside the NSIS executable will be shown here>

Pages
        Page[0]
                dlg_id:        0x0000006a
                wndproc_id:    0x00000000 ( PWP_LICENSE )
                prefunc:       0xffffffff
                showfunc:      0xffffffff
                leavefunc:     0xffffffff
                flags:         0x00000000 (  )
                caption:       0xffffffd8
                back:          0x00000000
                next:          0xffffffd4
                clicknext:     0xffffffd3
                cancel:        0xffffffd9
                params:        [0x0, 0xffffffd7, 0xffffffd6, 0x0, 0x0]
        Page[1]
                dlg_id:        0xffffffff
                wndproc_id:    0x0000000a ( <unknown> )
                prefunc:       0xffffffff
                showfunc:      0xffffffff
                leavefunc:     0xffffffff
                flags:         0x0000000a ( PF_NEXT_ENABLE | PF_BACK_SHOW )
                caption:       0xffffffd2
                back:          0xffffffd5
                next:          0xffffffd4
                clicknext:     0xffffffd3
                cancel:        0xffffffd9
                params:        [0x0, 0x0, 0x0, 0x0, 0x0]
        Page[2]
                dlg_id:        0x00000068
                wndproc_id:    0x0000000e ( <unknown> )
                prefunc:       0xffffffff
                showfunc:      0xffffffff
                leavefunc:     0xffffffff
                flags:         0x0000000e ( PF_NEXT_ENABLE | PF_CANCEL_ENABLE | PF_BACK_SHOW )
                caption:       0xffffffd1
                back:          0xffffffd5
                next:          0xffffffd4
                clicknext:     0xffffffd3
                cancel:        0xffffffd9
                params:        [0xffffffd0, 0xffffffcf, 0xffffffce, 0x0, 0xffffffcd]
        Page[3]
                dlg_id:        0x00000067
                wndproc_id:    0x0000010a ( <unknown> )
                prefunc:       0xffffffff
                showfunc:      0xffffffff
                leavefunc:     0xffffffff
                flags:         0x0000010a ( PF_NEXT_ENABLE | PF_BACK_SHOW | PF_BACK_ENABLE )
                caption:       0xffffffcc
                back:          0xffffffd5
                next:          0xffffffc7
                clicknext:     0x00000000
                cancel:        0xffffffd9
                params:        [0xffffffcb, 0xffffffca, 0xffffffc9, 0xffffffc8, 0x15]

Entries
        size:          0x00000058

Sections
        Section[0] - Ydrelrernes
                name_ptr:      Ydrelrernes @ 0x00000130
                name_ptr:      Ydrelrernes @ 0x00000130
                install_types: 0x00000000
                flags:         0x00000001 ( SF_SELECTED )
                code:          0x00000029
                code_size:     0x0000002e
                size_kb:       0x00002b42
                name:          : “”

LangTable
                Lang ID:       0x00000409
                LangTable Strings Num: 0x0000003a
                “0=Asaddle”
                “1=Pressechefers”
                “2=Counteracting”
                “3=jern”
                “4=Skrmmiljet”
                “5=Can’t write: “
                “17=Error decompressing data! Corrupted installer?”
                “18=”
                “19=ExecShell: “
                “20=Execute: “
                “21=Extract: “
                “22=Extract: error writing to file “
                “25=Output folder: “
                “29=Skipped: “
                “30=Copy Details To Clipboard”
                “32=B”
                “33= K”
                “34= M”
                “35= G”
                “36=Error opening file for writing:
$\r$\n$\r$\n$0$\r$\n$\r$\nClick Abort to stop the installation,$\r$\nRetry to try again, or$\r$\nIgnore to skip this file.”
                “37=Custom”
                “38=Cancel”
                “39=: Installing”
                “40=Show &details”
                “41=Completed”
                “42=< &Back”
                “43=&Next >“
                “44=Click Next to continue.”
                “45=: Completed”
                “46=: Installation Options”
                “47=Check the components you want to install and uncheck the components you don’t want to install. $CLICKNEXT”
                “48=Select the type of install:”
                “49=Or, select the optional components you wish to install:”
                “50=Select components to install:”
                “51=: Installation Folder”
                “52=Setup will install $(LSTR_57) in the following folder. To install in a different folder, click Browse and select another folder. $CLICKNEXT”
                “53=Destination Folder”
                “54=B&rowse...”
                “55=Select the folder to install $(LSTR_57) in:”
                “56=&Close”
                “57=Counteracting”
Methods
        “Offset=0x47c, End=0x9a0, Size=0x524, Name=Ydrelrernes”
        “Instructions:”
                “0x47c: CreateDir “$INSTALLDIR”, 0x1”
                “0x498: IfFileExists “$INSTALLDIR\Smore.dry”, label_674, label_4b4”
                “label_4b4:”
                “0x4b4: ExtractFile 0x5000090, “Smore.dry”, 0x0, 0xbb382a00, 0x1daa475, 0xffffffdb”
                “0x4d0: ExtractFile 0x5000090, “Knaphulsblomster201.Dri”, 0x40ef8, 0xbb382a00, 0x1daa475, 0xffffffdb”
                “0x4ec: ExtractFile 0x5000090, “Brsmatador113.den”, 0x4a011, 0xbb382a00, 0x1daa475, 0xffffffdb”
                “0x508: ExtractFile 0x5000090, “Butty.pac”, 0x7b459, 0xbb382a00, 0x1daa475, 0xffffffdb”
                “0x524: ExtractFile 0x5000090, “Coeltera.enh”, 0xa95d4, 0xbb382a00, 0x1daa475, 0xffffffdb”
                “0x540: CreateDir “$INSTALLDIR”, 0x1”
                “0x55c: ExtractFile 0x5000090, “femtenaarsfdselsdages.txt”, 0xae47b, 0xbb382a00, 0x1daa475, 0xffffffdb”
                “0x578: ExtractFile 0x5000090, “gooseskin.tra”, 0xae590, 0xbb382a00, 0x1daa475, 0xffffffdb”
                “0x594: AssignVar $__var37__, “6””
                “0x5b0: Jmp label_5e8”
                “label_5cc:”
                “0x5cc: IntOp $__var37__, “$__var37__”, “4”, 0x0”
                “label_5e8:”
                “0x5e8: IntCmp “$__var37__”, “44”, 0x0, 0x0, label_674, 0x0”
                “0x604: ShellExec “open”, “%SYSDIR%\palaestral.Int”, “”, “ProgramFilesDir””
                “0x620: Jmp label_5cc”
                “0x63c: Jmp label_5cc”
                “0x658: Jmp label_674”
                “label_674:”
                “0x674: IntFmt $5, “%c”, “0x22””
                “0x690: AssignVar $5, “   $5””
                “0x6ac: AssignVar $8, “$INSTALLDIR\Knaphulsblomster201.Dri””
                “0x6c8: AssignVar $2, “ ep$$.nsh arjGa e B,r altBj eRe rRe k ugn.ong ohtAc,=,im$$Di A U.bC ns A,cba iO.fsJa s D.e ioaSt kUn,sGn eH,pnA,l.Si S M uTr b D SP yt U,r L i yln ovg ,g(  u5Pa,8 az0  a3  n6 or,U,d3R,i)””
                “0x6e4: DeleteRegKey 0x0, “”, “bekostningernes\verbalerotik”, “amtsgymnasier””
                “0x700: Push “Resu$5.ub$$ asA mabIp s A.c .tiBo sH ts S e era ock .esCh e ,anF,s= auG oleP,atSa - T.C,iloCh,n,ilt E e arnT atSa  E,o- igRL raN nwPh  Ka ‘””
                “0x71c: Pop $__var58__”
                “0x738: Call sub_0x0”
                “0x754: Pop $6”
                “0x770: FindFirst $__var35__, $__var34__, “%PROFILE%\*.cur””
                “0x78c: AssignVar $4, “Fl r ol’ ic;$2H.e;u,s.C r$$li.h,sbj,eleU dr,emt C,e.lurs lkC,mnB,dgOp th.n( ,e$$A tA dab,ngs alcOo iG zsU msSl epi aS.uk hosUd eD.enDr )””
                “0x7a8: AssignVar $4, “$4$5””
                “0x7c4: AssignVar $__var58__, “$4””
                “0x7e0: FileClose $__var33__”
                “0x7fc: Call sub_0x0”
                “0x818: Pop $__var57__”
                “0x834: AssignVar $3, “$__var57__””
                “0x850: ReadRegValue $__var32__, 0x80000002, “dumpningstallets\Uninstall\Elbuck”, “Plyndringerne”, 0x1”
                “0x86c: Push “Brew,dep,lnoE,kwE se knrtu s D h.one r lI,tl ak. j eH dx.hae ra  rv- rawR piB.knY md  no,yswAr sSk t cey.vrlTi e ap p lhHu i ltdBa,d s eCa n””
                “0x888: Pop $4”
                “0x8a4: AssignVar $__var58__, “$4””
                “0x8c0: WriteRegValue 0x80000002, “teleplasmaens\Slabs\vigge”, “Gamesmen”, 0xcef6e, 0x3”
                “0x8dc: Call sub_0x0”
                “0x8f8: Pop $0”
                “0x914: Execute “$__var62__$0 $6$8$3$__var62__”, 0x0, 0x0”
                “0x930: WriteRegValue 0x80000002, “seafronts\kartove\kretid”, “euchysiderite”, 0x531, 0x1”
                “0x94c: StrCmp “$__var36__”, “cheris”, label_968, label_984, 0x0”
                “label_968:”
                “0x968: Quit”
                “label_984:”
                “0x984: Return”
        “Instructions End”
“Dumping script contents to Script.nsi”

The text above is the result of the nsisdump.py utility when run on a malicious NSIS executable. NRS is capable of obtaining block information, strings and header information. Additions have been made to allow nsisdump.py to properly dump NSIS function code as well as properly parse UTF-16LE binaries.

To ensure that NRS could fully parse the NSIS executables we would see on a regular basis, we made modifications to add support for additional types of NSIS files to our fork of the library. For instance, we added support for NSIS 2 UTF-16LE executables. Unicode strings are not supported on NSIS 2.x executables by default; however, additional versions of NSIS 2.x have been released that contain the functionality. A significant portion of the executables we observed utilized this version of NSIS. In order to be able to parse information from executables that utilize this version of NSIS, we added support for NSIS 2.x UTF-16LE into NRS.

In addition to adding NSIS 2.x Unicode support, we also added support for method disassembly to NRS. Disassembling the NSIS script is extremely important when parsing NSIS executables. Information regarding embedded files and actions taken on the system is only stored within the various instructions of the script. In order to allow parsing of this information, we added a disassembler to NRS. The disassembler is capable of finding the various script methods embedded within the NSIS executable and outputting disassembly for all present methods. The dump output above shows an example of what the disassembly output may look like. Instructions such as ExtractFile are used to obtain the embedded files within the installer. In addition to disassembling various methods, we added support for dumping the contents of the NSIS script to a file or string. The result generally looks similar to how 7-Zip would decompile NSIS scripts.

All together, NRS was a great expansion of our capabilities to parse and extract information from NSIS executables.

GuloaderDumper

GuloaderDumper is a tool created to assist with the analysis of a specific family of malware samples. During the analysis of various malicious loaders, X-Force analysts will often attempt to create scripts to parse the payloads of various loader families. Normally, this works very well: the initial executable is submitted to our analysis pipeline, which then automatically unpacks and extracts the payload using a parser specific to the submitted loader family. Certain loaders may contain advanced features that require additional work in order to automatically unpack. Guloader is a great example of this. Guloader is a commodity loader that commonly makes use of NSIS executables as the initial binary. The NSIS executable will eventually load guloader shellcode, which is used to further stage and execute the payload. Guloader contains many obfuscation mechanisms, some of which are detailed here. Because of the impressive amount of obfuscation mechanisms present in Guloader and the fact that the encrypted payload is downloaded from a remote URL during execution, we had to think outside the box in order to create a tool that would allow for the automatic unpacking of Guloader executables. In order to accomplish this task, we created GuloaderDumper.

Unlike most of our other tools, GuloaderDumper is designed as a kernel module. This allows GuloaderDumper to bypass most of Guloader’s user-mode anti-analysis checks, preventing execution from terminating prematurely.

GuloaderDumper contains two components: a runner script written in Python and the kernel module itself. The runner script is used to execute the initial Guloader executable and inform GuloaderDumper which process it should track for injection.

The above code is used to keep track of which process GuloaderDumper should target. The DeviceIoControl() function will result in a handler being called kernel side, which will cause GuloaderDumper to begin tracking the newly created Guloader process.

Once the kernel module begins tracking a process for injection, it will keep track of any child processes it spawns. Guloader will normally spawn at least one child process in order to inject the payload. GuloaderDumper utilizes process notify callbacks in order to keep track of which process Guloader will eventually inject a payload into.

In order to properly dump the payload, GuloaderDumper must also keep track of when injection has completed. For Guloader, this occurs after the connection to the site hosting the encrypted payload has closed. Filter callbacks may be used to determine when a tracked connection closes.

Using filter callbacks, GuloaderDumper will create a work item to suspend the target process and begin dumping shortly after the connection between the victim and the C2 holding the encrypted payload has terminated. At this point, the payload is likely within the memory space of the target process. A unique trait of Guloader’s process injection method may then be used to determine where exactly the injected payload is located in memory. When a PE file is loaded into a process as a library, it is usually added to the InMemoryOrderModuleList structure within the process’s PEB. This list should, for the most part, only contain DLL files. Guloader adds an entry to this list that contains an EXE file instead of a DLL. Using this unique trait, GuloaderDumper can determine exactly where the payload is located.

Once the memory space that contains the payload is obtained, GuloaderDumper processes the output in order to ensure that the dumped executable will be sufficient for analysis. This includes parsing the executable from virtual memory space and mapping it to an on-disk file, as well as adjusting the base address of the executable in order to ensure relocations work properly.

Once the dumped memory is processed, it will be written to the filesystem for further analysis.

DotNetUtils

DotNetUtils is a library created by X-Force to parse, emulate, patch and deobfuscate various .NET executables. These executables are very popular with various families of commodity malware, including RoboSki, VIPKeylogger, Snake Logger, XWorm and others. Malicious .NET executables usually come packed or obfuscated by tools such as ConfuserEx, .NETReactor and Eazfuscator. These tools hide the method code, method control flow, function names and other important items from analysts.

In the above snippet of code, a few things stick out:

  • The method names consist of random junk characters.
    • This is a common trick used by most obfuscators to hinder analysis by making it harder for analysts to track function calls by name.
  • There are no imported methods being called.
    • ConfuserEx especially will hide imported methods inside another method in order to confuse analysts. Some obfuscators will also replace imported method calls with calls to a MulticastDelegate.
  • The control flow is randomized.
    • C# obfuscators will commonly use for loops and switch statements in order to obfuscate the control flow of a method.
  • The strings are hidden behind a method that takes an integer as a parameter.
    • Obfuscators will commonly replace string and constant initialization with a call to a method that decrypts the strings at runtime. Generally, these methods take one parameter, usually an integer. They almost always return a string.

The combination of all of these measures makes it difficult for an analyst to properly examine the executable. DotNetUtils was designed with obfuscated files in mind. DotNetUtils contains features that allow analysts to create scripts capable of removing these protections. For example, the above snippet of code can be transformed using DotNetUtils to look like this:

The above code is much more readable and informative to an analyst. To remove the obfuscation, a simple script was created that emulates the string obfuscation method and replaces the call with an instruction to load the deobfuscated string (the .NET CIL ldstr instruction).

Once the obfuscated string references are removed, dotnetutils.net_deobfuscate_funcs.cleanup_names() can be called to change all of the names in the metadata tables to a name that is more readable to analysts. Unfortunately, in most cases, it is unlikely that the original names can be recovered. Additionally, dotnetutils.net_deobfuscate_funcs.remove_useless_functions() can be used to remove method calls that simply invoke another imported function. These actions result in the above code, which is significantly more readable than the original.

In addition to containing utilities to remove common obfuscation tricks, DotNetUtils is also capable of parsing the metadata tables and method code of a .NET executable. This functionality can be used in scripting to pull important information from a binary. For instance, it is possible to obtain important Indicators of Compromise (IOC) from the method code:

The code above is used to obtain a port value, which is stored as a string. In .NET executables, static variables are initialized within a type’s static constructor. This snippet of code parses the static constructor in order to obtain the port value. Additionally, DotNetUtils exposes all elements of the .NET metadata tables in the form of Python objects. This functionality can be utilized by scripts in order to get a Python-compatible object representing any value from the .NET metadata tables. This can be useful for obtaining function names, field names or even default field values.

Finally, DotNetUtils also contains a partial .NET Common Intermediate Language (CIL) emulator. The emulator is capable of emulating complicated .NET functions, including the string deobfuscation functions for various obfuscators. DotNetEmulator supports boxing and unboxing, unsigned math operations, signed math operations, array allocations, basic multicast delegates, basic dynamic methods and object creation. DotNetEmulator is written in Cython in order to improve speed and memory management. Users can pull the results of an emulation using the functions related to the DotNetEmulator class. DotNetEmulator can be used to assist with string obfuscation, payload extraction and other functionalities. For example, DotNetEmulator may be used in conjunction with method patching to remove the delegate proxy obfuscation from a .NET Reactor executable.

In the above code snippet, there are no calls to imported methods. That is because they are hidden behind delegate calls and dynamic methods. DotNetEmulator is capable of properly emulating these delegate calls. It is also possible to use the emulator to assist with obtaining the mapping between the various proxy calls and their resolved methods. 

Once DotNetEmulator finishes obtaining the dictionary that contains the mapping between the delegate calls and their resolved methods, dotnetutils.dotnetpefile.DotNetPeFile.patch_instruction() can be used to replace the delegate calls with their resolved functions.

The above snippet of code removes the ldsfld instruction that loads the delegate class by replacing it with 0x00, or a nop instruction. Next, it will replace the call to MulticastDelegate.Invoke() with a call or callvirt to the resolved method. Once finished, the code will be more readable to an analyst.

With the delegates removed, the imported methods being called are clear to the analyst.

What's next?

As we continue to utilize these projects against more malicious samples, X-Force may continue to add updates as needed to ensure that these tools remain useful. For tools such as GuloaderDumper and NRS, this will include ensuring these tools are capable of supporting the latest versions of their targeted executables. For dotnetutils, new features such as control flow deobfuscation, method encryption deobfuscation and better dynamic method handling may eventually be added. We also welcome any suggestions or contributions from the community via our GitHub page, located here.

IBM X-Force Premier Threat Intelligence is now integrated with OpenCTI by Filigran, delivering actionable threat intelligence about this threat activity and more. Access insights on threat actors, malware, and industry risks. Install the X-Force OpenCTI Connector to enhance detection and response, strengthening your cybersecurity with IBM X-Force’s expertise. Get a 30-Day X-Force Premier Threat Intelligence trial today!

Would your team catch the next zero-day in time?

Join security leaders who rely on the Think Newsletter for curated news on AI, cybersecurity, data and automation. Learn fast from expert tutorials and explainers—delivered directly to your inbox. See the IBM Privacy Statement.

Your subscription will be delivered in English. You will find an unsubscribe link in every newsletter. You can manage your subscriptions or unsubscribe here. Refer to our IBM Privacy Statement for more information.

https://www.ibm.com/us-en/privacy
Related solutions
IBM Verify

Build a secure, vendor-agnostic identity framework that modernizes IAM, integrates with existing tools, and enables seamless hybrid access without added complexity.

Explore IBM verify
Threat detection response solutions

Accelerate response by prioritizing high-impact risks and automating remediation across teams.

Explore threat detection response solutions
IBM Cyber Threat Management

Predict, prevent, and respond to modern threats to strengthen business resilience.

Explore IBM cyber threat management
Take the next step

Discover how IBM Verify modernizes IAM by integrating with your existing tools to deliver secure, seamless hybrid identity access.

Discover IBM Verify Explore threat detection response solutions